#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unix_sock.h>
#include <log_utils.h>
#include "cJSON.h"

static struct unix_param unix_para;

#define MODULE_UNIX "unixs_modbus"
#define N 64

//全局变量

//发送命令缓冲区
unsigned char send_buf[128] = {0x02,0xb7,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x00,0x00,0x02};

//线程操作函数1
void *thread(void *arg)
{
    char data[256] = {0};
    cJSON* root = NULL;
    cJSON* item = NULL;
    cJSON* value_json = NULL;
    cJSON* key_json = NULL;
    //线程开启UNIX接受上报进程的控制指令
    unix_init_server(&unix_para, MODULE_UNIX);
    while(1)
    {
        if(unix_server_recv(&unix_para, data, 256) > 0)
        {
            root = cJSON_Parse(data);
            if(!root)
            {
                printf("Error control from thread!\n");
            } 
            else
            {
                item = cJSON_GetObjectItem(root,"data");
                key_json = cJSON_GetObjectItem(item,"key");
                value_json = cJSON_GetObjectItem(item,"val");
                printf("val:->%s\n",value_json->valuestring);
                printf("key:->%d\n",key_json->valueint);
            }
            
        }
    }
}


int conver_endian_long(unsigned char *dst, const unsigned char *src, int len)
{
    int i = 0;

    if(len % 4 != 0){
        printf("err len\n");
        return -1;
    }

    while (i < len) {
        dst[i] = src[i+3];
        dst[i+1] = src[i+2];
        dst[i+2] = src[i+1];
        dst[i+3] = src[i];
        i += 4;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    // 0定义变量
    int sockfd;
    pthread_t tid;
    int a = 20;
    int addrlen = sizeof(struct sockaddr);
    struct sockaddr_in serveraddr;

    if(argc != 3){
        printf("usage: %s <ip> <port>\n", argv[0]);
        return -1;
    }

    // 1创建一个套接字--socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        perror("socket err");
        exit(-1);
    }

    // 2指定服务器地址--sockaddr_in
    bzero(&serveraddr, addrlen);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    // 3连接服务器--connect
    if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0){
        perror("connect err");
        exit(-1);
    }
    printf("服务器连接成功!\n");
    
    /*
    02 b7：事务标识符，类似与TCP里的seq和ack，可以随意写，回复和发送的会一致
    00 00：协议标识符，00 00表示ModbusTCP协议
    00 06：表示接下来的数据长度，单位为字节
    01：单元标识符，即新建寄存器表时候的从机ID，默认是1。
    03：功能码，我们现在读的是保持寄存器，所以是03
    00 00：读取的起始寄存器地址
    00 01：读取的寄存器个数 */

    

    //接收缓冲区
    unsigned char recv_buf[128] = {0};
    
    if(pthread_create(&tid,NULL,thread,&a) != 0)
	{
		perror("pthread_create err.");
		return -1;
	}
    while(1)
    {
        send(sockfd, send_buf, 12, 0);
        int ret = recv(sockfd, recv_buf, 128, 0);
        if(ret < 0)
        {
            perror("recv err");
            continue;
        }

        int i;
        for(i=0; i<ret; i++)
        {
            //将接收的内容打印出来看看
            printf("%02x ", recv_buf[i]);
        }
        printf("\n");

        //解析出需要的数据来
        float *p = recv_buf + 9;  //将指针偏移到数据位置

/*
#if 1   //因为接收的数据是按照大端ABCD存储的，而我们的CPU是小端模式，所以要将字节序置换     
        float data;
        conver_endian_long(&data, p, 4);
#else   //如果接收数据格式是DCBCA（小端）存储，那么就简单了，直接定义一个float类型指针变量，指向这四个字节即可取出值来
        float data = *p;
#endif*/

		float data = *p;
        printf("temp = %0.2f\n", data);

        //将数据结构体发送到共享内存中
        sleep(1);
    }


    // 5关闭连接--close
    close(sockfd);
}
